home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / dsp / dsp56k / a56-1_0.lha / a56-1.0 / main.c < prev    next >
C/C++ Source or Header  |  1993-08-09  |  6KB  |  365 lines

  1. /*******************************************************
  2.  *
  3.  *  a56 - a DSP56001 assembler
  4.  *
  5.  *  Written by Quinn C. Jensen
  6.  *  July 1990
  7.  *  jensenq@npd.novell.com (or jensenq@qcj.icon.com)
  8.  *
  9.  *******************************************************\
  10.  
  11. /*
  12.  * Copyright (C) 1990, 1991 Quinn C. Jensen
  13.  *
  14.  * Permission to use, copy, modify, distribute, and sell this software
  15.  * and its documentation for any purpose is hereby granted without fee,
  16.  * provided that the above copyright notice appear in all copies and
  17.  * that both that copyright notice and this permission notice appear
  18.  * in supporting documentation.  The author makes no representations
  19.  * about the suitability of this software for any purpose.  It is
  20.  * provided "as is" without express or implied warranty.
  21.  *
  22.  */
  23. static char *Copyright = "Copyright (C) 1990, 1991 Quinn C. Jensen";
  24.  
  25. /*
  26.  *  main.c - The "main" code for the assembler.
  27.  *
  28.  */
  29.  
  30. #include "a56.h"
  31.  
  32. #define MAX 1024
  33.  
  34. int pass;
  35. int error;
  36. extern unsigned long pc;
  37. extern int seg;
  38. BOOL binary_listing = FALSE;
  39. FILE *obj = NULL;
  40. BOOL list_on = TRUE;
  41. char *alloc();
  42.  
  43. main(argc,argv)
  44. int argc;
  45. char *argv[];
  46. {
  47.     int i;
  48.     obj = open_write("a56.out");
  49.  
  50.     if(argc > 2 && strcmp(argv[1], "-b") == 0) {
  51.     binary_listing++;
  52.     argc--;
  53.     argv++;
  54.     }
  55.  
  56.     pc = 0;
  57.     seg = 0;
  58.     pass = 1;
  59.     reset_psects();
  60.     include(argv[1]);
  61.  
  62.     pc = 0;
  63.     seg = 0;
  64.     pass = 2;
  65.     reset_psects();
  66.     include(argv[1]);
  67.  
  68.     dump_symtab();
  69.     fclose(obj);
  70.     printf("errors=%d\n", error);
  71.     return(error ? 1 : 0);
  72. }
  73.  
  74. struct inc inc[MAX_NEST];
  75. int inc_p = 0;
  76.  
  77. include(file)
  78. char *file;
  79. {
  80.     FILE *fp = open_read(file);
  81.     extern FILE *yyin;
  82.  
  83.     inc_p++;
  84.     if(inc_p >= MAX_NEST)
  85.     fatal("%s: include nesting too deep\n", file);
  86.  
  87.     inc[inc_p].file = file;
  88.     inc[inc_p].fp = fp;
  89.     inc[inc_p].line = 0;
  90.  
  91.     list_on = TRUE;
  92.     if(inc_p > 1)
  93.     list_on = FALSE;
  94.  
  95.     yyin = inc[inc_p].fp;
  96.     if(inc_p == 1)
  97.     yyparse();
  98. }
  99.  
  100. yywrap()
  101. {
  102.     fclose(inc[inc_p].fp);
  103.     inc_p--;
  104.     list_on = TRUE;
  105.     if(inc_p > 1)
  106.     list_on = FALSE;
  107.     if(inc_p) {
  108.     yyin = inc[inc_p].fp;
  109.     return(0);
  110.     } else {
  111.     return(1);
  112.     }
  113. }
  114.  
  115. sym_ref(sym)    /* return symbol value or -1 if not defined yet */
  116. char *sym;
  117. {
  118.     struct sym *sp, *find_sym();
  119.     char msg[128];
  120.  
  121.     sp = find_sym(sym);
  122.     if(NOT sp) {
  123.     if(pass == 2) {
  124.         sprintf(msg, "%s: undefined symbol", sym);
  125.         yyerror(msg);
  126.     }           
  127.     return(-1);
  128.     }
  129.     return(sp->val);
  130. }
  131.  
  132. #define HASHSIZE 32
  133.  
  134. #define HASH(sym) ((sym)[0] % HASHSIZE)
  135.  
  136. struct sym *symtab[HASHSIZE];
  137.  
  138. sym_def(sym, val)
  139. char *sym;
  140. int val;
  141. {
  142.     struct sym *sp, **stop, *find_sym();
  143.  
  144.     if(pass == 1) {
  145.     if(find_sym(sym)) {
  146.         pass = 2;        /* what a kludge */
  147.         yyerror("multiply defined symbol");
  148.         pass = 1;
  149.         return;
  150.     }
  151.     stop = &symtab[HASH(sym)];
  152.     sp = NEW(struct sym);
  153.     sp->next = *stop;
  154.     *stop = sp;
  155.     sp->name = strsave(sym);
  156.     sp->val = val & 0xFFFFFF;
  157.     }
  158. }
  159.  
  160. struct sym *find_sym(sym)
  161. char *sym;
  162. {
  163.     struct sym *sp, **stop;
  164.  
  165.     stop = &symtab[HASH(sym)];
  166.     for(sp = *stop; sp; sp = sp->next)
  167.     if(strcmp(sp->name, sym) == 0)
  168.         return(sp);
  169.     
  170.     return(NULL);
  171. }
  172.  
  173. dump_symtab()
  174. {
  175.     struct sym *sp, **stop;
  176.     int i;
  177.  
  178.     printf("\nSymbol Table\n");
  179.  
  180.     for(i = 0, stop = symtab; i < HASHSIZE; i++, stop++) {
  181.     for(sp = *stop; sp; sp = sp->next) {
  182.         printf("%16s %06X\n", sp->name, sp->val);
  183.     }
  184.     }   
  185. }
  186.  
  187. char *printcode(word)
  188. int word;
  189. {
  190.     static char list[MAX], *lp;
  191.     int i;
  192.  
  193.     word &= 0xFFFFFF;
  194.  
  195.     if(binary_listing) {
  196.     sprintf(list, "%06X<", word);
  197.     for(i = 0, lp = &list[7]; i < 24; i++, lp++) {
  198.         *lp = word & 1 << 23 - i ? '1' : '0';
  199.         if(i && i % 4 == 3)
  200.         *++lp = i % 8 == 7 ? ' ' : ',';
  201.     }
  202.     lp[-1] = '>';
  203.     lp[0] = '\0';
  204.     } else {
  205.     sprintf(list, "%06X", word);
  206.     }
  207.     return(list);
  208. }
  209.  
  210. char *spacespace[2] = {
  211. /*P:XXXX_XXXXXX_*/
  212.  "              ",
  213. /*P:XXXX_XXXXXX(XXXX_XXXX_XXXX_XXXX_XXXX_XXXX)_*/
  214.  "                                             "};
  215. char *spaces(n)
  216. int n;
  217. {
  218.     return(&spacespace[binary_listing ? 1 : 0][n]);
  219. }
  220.  
  221. gencode(seg, pc, word)
  222. int seg, pc, word;
  223. {
  224.     extern char segs[];
  225.  
  226.     fprintf(obj, "%c %04X %06X\n", segs[seg], pc, word & 0xFFFFFF);
  227. }
  228.  
  229. char fixbuf[1024];
  230.  
  231. char *fixstring(s)
  232. char *s;
  233. {
  234.     char *bp = fixbuf;
  235.     int ival;
  236.  
  237.     while(*s) {
  238.     switch (*s) {
  239.         case '\'':
  240.         s++;
  241.         break;
  242.         case '\\':
  243.         switch (*++s) {
  244.             case 'b': *bp++ = '\b'; break;
  245.             case 'r': *bp++ = '\r'; break;
  246.             case 'f': *bp++ = '\f'; break;
  247.             case 'n': *bp++ = '\n'; break;
  248.             case 't': *bp++ = '\t'; break;
  249.             case '\\': *bp++ = '\\'; break;
  250.             case '0':
  251.             ival = 0;
  252.             while(*s >= '0' && *s <= '9') {
  253.                 ival <<= 3;
  254.                 ival += *s++ - '0';
  255.             }
  256.             *bp++ = ival;
  257.             break;
  258.         }
  259.         break;
  260.         default:
  261.         *bp++ = *s++;
  262.         break;
  263.     }
  264.     }
  265.     *bp = '\0';
  266.     return(fixbuf);
  267. }
  268.  
  269. #define ONE 0x4000000
  270.  
  271. makefrac(s)
  272. char *s;
  273. {
  274.     int frac = 0, div = 1;
  275.     int scale = 1;
  276.  
  277.     while(*s) {
  278.     switch(*s) {
  279.         case '-':
  280.         scale = -1;
  281.         break;
  282.         case '.':
  283.         div = 10;
  284.         break;
  285.         default:
  286.         frac += (*s - '0') * scale * ONE / div;
  287.         div *= 10;
  288.         break;
  289.     }
  290.     s++;
  291.     }
  292.  
  293.     return(frac + scale * 4 >> 3 & 0xFFFFFF);
  294. }
  295.  
  296. /***************** psect stuff ************************/
  297.  
  298. struct psect *ptop = NULL, *cur_psect = NULL;
  299.  
  300. reset_psects()
  301. {
  302.     struct psect *pp;
  303.  
  304.     for(pp = ptop; pp; pp = pp->next)
  305.     pp->pc = pp->bottom;
  306.  
  307.     set_psect(NULL);
  308. }
  309.  
  310. struct psect *find_psect(name)
  311. char *name;
  312. {
  313.     struct psect *pp;
  314.  
  315.     for(pp = ptop; pp; pp = pp->next)
  316.     if(strcmp(pp->name, name) == 0)
  317.         return(pp);
  318.  
  319.     return(NULL);
  320. }
  321.  
  322. set_psect(pp)
  323. struct psect *pp;
  324. {
  325.     cur_psect = pp;
  326. }
  327.  
  328. check_psect(seg, pc)
  329. int seg;
  330. unsigned int pc;
  331. {
  332.     if(cur_psect) {
  333.     if(seg == cur_psect->seg && pc >= cur_psect->bottom && 
  334.         pc <= cur_psect->top) {
  335.         cur_psect->pc = pc;
  336.         return(TRUE);
  337.     } else {
  338.         return(FALSE);
  339.     }
  340.     } else {
  341.     return(TRUE);
  342.     }
  343. }
  344.  
  345. struct psect *new_psect(name, seg, bottom, top)
  346. char *name;
  347. int seg;
  348. unsigned int bottom, top;
  349. {
  350.     struct psect *pp = find_psect(name);
  351.  
  352.     if(NOT pp) {
  353.     pp = (struct psect *)alloc(sizeof *pp);
  354.     pp->next = ptop;
  355.     ptop = pp;
  356.     pp->name = strsave(name);
  357.     pp->seg = seg;
  358.     pp->pc = bottom;
  359.     }
  360.     pp->bottom = bottom;
  361.     pp->top = top;
  362.  
  363.     return(pp);
  364. }
  365.